<!-- 大播放器的进度条组件 -->
<template>
  <!-- 总长度 -->
  <div class="progress-bar" ref="progressBar" @click="progressClick">
    <div class="bar-inner" >
      <!-- 偏移的位置 -->
      <div class="progress" ref="progress"></div>
      <!-- 当前的位置滑动小球 -->
      <!-- 给小球添加滑动事件，操作歌曲播放进度 -->
      <!-- 一般给touch事件都要取消默认行为prevent -->
      <div class="progress-btn-wrapper" ref="progressBtn"
           @touchstart.prevent="progressTouchStart"
           @touchmove.prevent="progressTouchMove"
           @touchend.prevent="progressTouchEnd">
        <div class="progress-btn"></div>
      </div>
    </div>
  </div>
</template>

<script>
// 引入自定义的浏览器兼容性函数
import {prefixStyle} from 'common/js/dom'
// 小球的宽度是16px
const progressBtnWidth = 16

const transform = prefixStyle('transform')

export default {
  props: {
    // 接收的百分比
    percent: {
      type: Number,
      default: 0
    }
  },
  // vue实例选项都初始化后自动调用的函数
  created () {
    // 来维护不同touch回调函数之间的通信,共享数据
    this.touch = {}
  },
  methods: {
    // touch的开始
    progressTouchStart (e) {
      // 定一个标识位,Boolean
      this.touch.initiated = true
      // 第一个手指的x轴坐标
      this.touch.startX = e.touches[0].pageX
      // 已经偏移的宽度
      this.touch.left = this.$refs.progress.clientWidth
    },
    // touch的移动
    progressTouchMove (e) {
      // 判断如果没有经过touchstart直接进入touchmove
      if (!this.touch.initiated) {
        // 跳出函数
        return
      }
      // 第一个手指的x轴位置减掉之前存的x轴位置
      // 滑动了的偏移量
      const deltaX = e.touches[0].pageX - this.touch.startX
      // 0到已经偏移的宽度加上活动的偏移量
      // 用Math.max来限制拖动到超出左边
      // 当拖动到大于整个长度的时候，肯定不行的,用Math.min来限制
      // offsetWidth就是移动之后的宽度或者说偏移位置
      const offsetWidth = Math.min(this.$refs.progressBar.clientWidth - progressBtnWidth, Math.max(0, this.touch.left + deltaX))
      // 设置进度和小球的偏移
      this._offset(offsetWidth)
    },
    // touch的结束
    progressTouchEnd () {
      // 标识位重置
      this.touch.initiated = false
      // 手指抬起的时候，应该派发一个事件
      this._triggerPercent()
    },
    // 点击进度条事件
    progressClick (e) {
      // 设置进度和小球的偏移
      // e事件对象offsetX是相对当前坐标系的border左上角开始的坐标
      // 需要注释的是当我们点击progessBtn的时候，e.offsetX 获取不对
      // this._offset(e.offsetX)
      // getBoundingClientRect()返回元素的大小及其相对视口的位置
      // 这里的getBoundingClientRect().left即使进度条起点到屏幕左侧的距离
      const rect = this.$refs.progressBar.getBoundingClientRect()
      const offsetWidth = e.pageX - rect.left
      // 设置进度和小球的偏移
      this._offset(offsetWidth)
      // 给父组件派发事件,拖动的到的位置和总长度的比例
      this._triggerPercent()
    },
    // 给父组件派发事件,拖动的到的位置和总长度的比例
    _triggerPercent () {
      // 先拿到进度条总长度
      const barWidth = this.$refs.progressBar.clientWidth - progressBtnWidth
      // 已经偏移的宽度除以总长度得出一个现在的比例
      const percent = this.$refs.progress.clientWidth / barWidth
      // 把这个比例传递给父组件
      this.$emit('percentChange', percent)
    },
    // 设置进度和小球的偏移
    _offset (offsetWidth) {
      // 设置当前进度偏移的宽度
      this.$refs.progress.style.width = `${offsetWidth}px`
      // 设置当前小球偏移的宽度
      this.$refs.progressBtn.style[transform] = `translate3d(${offsetWidth}px,0,0)`
    }
  },
  watch: {
    // 监听percent从父组件传来的值，准备作为百分比用
    percent (newPercent) {
      // 如果传过过来的百分比大于等于0
      // 为了拖动小球不被干扰加入条件,没有touch事件调用时候执行进度条偏移
      if (newPercent >= 0 && !this.touch.initiated) {
        // 获取进度的宽度=整个进度条元素总宽度-小圆点的宽度16px
        const barWidth = this.$refs.progressBar.clientWidth - progressBtnWidth
        // 当前应该偏移宽度
        const offsetWidth = newPercent * barWidth
        // 设置进度和小球的偏移
        this._offset(offsetWidth)
      }
    }
  }
}
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
  @import "~common/stylus/variable"

  .progress-bar
    height: 30px
    .bar-inner
      position: relative
      top: 13px
      height: 4px
      background: rgba(0, 0, 0, 0.3)
      .progress
        position: absolute
        height: 100%
        background: $color-theme
      .progress-btn-wrapper
        position: absolute
        left: -8px
        top: -13px
        width: 30px
        height: 30px
        .progress-btn
          position: relative
          top: 7px
          left: 7px
          box-sizing: border-box
          width: 16px
          height: 16px
          border: 3px solid $color-text
          border-radius: 50%
          background: $color-theme
</style>
